;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.BitUtil = factory();
    }
})($videojsTools, function(){
    let bitUtil = {};
    function checkLength(byteGetter, index, length){
        return byteGetter.valid(index + length);
    }

    function makeChar(b1, b0){
        return String.fromCharCode((b1 << 8) | (b0 & 0xff));
    }
    function makeShort(b1, b0){
        return (b1 << 8) | (b0 & 0xff)
    }
    function get2ByteB(func, byteGetter, index){
        return func(byteGetter.get(index), byteGetter.get(index+1));
    }
    function get2ByteL(func, byteGetter, index){
        return func(byteGetter.get(index+1), byteGetter.get(index));
    }


    function makeInt(b3, b2, b1, b0){
        return (((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) |
            ((b1 & 0xff) <<  8) | (b0 & 0xff));
    }
    function get4ByteB(func, byteGetter, index){
        return func(byteGetter.get(index), byteGetter.get(index+1), byteGetter.get(index+2), byteGetter.get(index+3));
    }
    function get4ByteL(func, byteGetter, index){
        return func(byteGetter.get(index+3), byteGetter.get(index+2), byteGetter.get(index+1), byteGetter.get(index))
    }

    function makeFloat(b3, b2, b1, b0){
        let buffer = new ArrayBuffer(4);
        let float = new Uint8Array(buffer);
        float[0] = b3;
        float[1] = b2;
        float[2] = b1;
        float[3] = b0;
        var dataView = new DataView(buffer, 0, 4);
        return dataView.getFloat32(0);
    }

    function makeLong(b7, b6, b5, b4, b3, b2, b1, b0){
        return  ((b7 & 0xff) << 56) | ((b6 & 0xff) << 48) |
            ((b5 & 0xff) << 40) | ((b4 & 0xff) << 32) |
            ((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) |
            ((b1 & 0xff) <<  8) | ((b0 & 0xff));
    }
    function get8ByteB(func, byteGetter, index){
        return func(
            byteGetter.get(index  ), byteGetter.get(index+1),
            byteGetter.get(index+2), byteGetter.get(index+3),
            byteGetter.get(index+4), byteGetter.get(index+5),
            byteGetter.get(index+6), byteGetter.get(index+7));
    }
    function get8ByteL(func, byteGetter, index){
        return func(
            byteGetter.get(index+7), byteGetter.get(index+6),
            byteGetter.get(index+5), byteGetter.get(index+4),
            byteGetter.getChar(index+3), byteGetter.get(index+2),
            byteGetter.get(index+1), byteGetter.get(index  ));
    }

    function makeDouble(b7, b6, b5, b4, b3, b2, b1, b0){
        let buffer = new ArrayBuffer(8);
        let float = new Uint8Array(buffer);
        float[0] = b7;
        float[1] = b6;
        float[2] = b5;
        float[3] = b4;
        float[4] = b3;
        float[5] = b2;
        float[6] = b1;
        float[7] = b0;
        var dataView = new DataView(buffer, 0, 8);
        return dataView.getFloat64(0);
    }
    bitUtil.getChar = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 2)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get2ByteB(makeChar, byteGetter, index):get2ByteL(makeChar, byteGetter, index);
    }
    bitUtil.getShort = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 2)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get2ByteB(makeShort, byteGetter, index):get2ByteL(makeShort, byteGetter, index);
    }
    bitUtil.getInt = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 4)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get4ByteB(makeInt, byteGetter, index):get4ByteL(makeInt, byteGetter, index);
    }
    bitUtil.getFloat = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 4)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get4ByteB(makeFloat, byteGetter, index):get4ByteL(makeFloat, byteGetter, index);
    }
    bitUtil.getLong = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 8)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get8ByteB(makeLong, byteGetter, index):get8ByteL(makeLong, byteGetter, index);
    }
    bitUtil.getDouble = function(byteGetter, index, bigEndian){
        if (!checkLength(byteGetter, index, 8)){
            throw "ArrayIndexOutOfBoundsException";
        }
        return bigEndian?get8ByteB(makeDouble, byteGetter, index):get8ByteL(makeDouble, byteGetter, index);
    }


    //将数值写入到视图中，获得其字节数组
    function getUint8Array(len, setNum) {
        var buffer = new ArrayBuffer(len);  //指定字节长度
        setNum(new DataView(buffer));  //根据不同的类型调用不同的函数来写入数值
        return new Uint8Array(buffer); //创建一个字节数组，从缓存中拿取数据
    }
    function getDoubleBytes(num, bigEndian) {
        return getUint8Array(8, function (view) { view.setFloat64(0, num, !bigEndian); })
    }
    function getLongBytes(num, bigEndian) {
        return getUint8Array(8, function (view) { view.setBigInt64(0, num, !bigEndian); })
    }
    function getFloatBytes(num, bigEndian) {
        return getUint8Array(4, function (view) { view.setFloat32(0, num, !bigEndian); })
    }
    function getIntBytes(num, bigEndian) {
        return getUint8Array(4, function (view) { view.setInt32(0, num, !bigEndian); })
    }
    function getShortBytes(num, bigEndian) {
        return getUint8Array(2, function (view) { view.setInt16(0, num, !bigEndian); })
    }
    function getChar(c, bigEndian) {
        let num = e.charCodeAt(1);
        return getUint8Array(2, function (view) { view.setUint16(0, num, !bigEndian); })
    }


    bitUtil.putChar = function(byteSetter, char, bigEndian){
        byteSetter.put(getChar(char, bigEndian));
    }
    bitUtil.putShort = function(byteSetter, short, bigEndian){
        byteSetter.put(getShortBytes(short, bigEndian));
    }
    bitUtil.putInt = function(byteSetter, int, bigEndian){
        byteSetter.put(getIntBytes(int, bigEndian));
    }
    bitUtil.putFloat = function(byteSetter, float, bigEndian){
        byteSetter.put(getFloatBytes(float, bigEndian));
    }
    bitUtil.putLong = function(byteSetter, long, bigEndian){
        byteSetter.put(getLongBytes(long, bigEndian));
    }
    bitUtil.putDouble = function(byteSetter, double, bigEndian){
        byteSetter.put(getDoubleBytes(double, bigEndian));
    }

    bitUtil.byteArray2Hex = function(bytes) {
        if (!(bytes instanceof Array)) {
            throw "unsupported";
        }
        var str = "";
        for (var byte of bytes) {
            str += byte.toString(16);
        }
        return str;
    }

    bitUtil.hex2ByteArray = function(str) {
        if (!(str instanceof String)) {
            throw "unsupported";
        }
        var array = [];
        var index = 0;
        for (var i = 0, l = str.length; i < l; i += 2) {
            array[index++] =  parseInt("0x" + str[i] + str[i+1]);

        }
        return array;
    }

    return bitUtil;
});








;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.DataReader = factory();
    }
})($videojsTools, function() {
    return function(unit8Array) {
        var BitUtil = $videojsTools.BitUtil;
        let getter = {
            get: function(index) {
                return unit8Array[index];
            },
            valid: function(index) {
                return unit8Array.length > index;
            }
        }

        var position = 0;
        var bigEndian = true;
        return {
            read: function() {
                var r = getter.get(position);
                position += 1;
                return r;
            },
            readShort: function(customBigEndian) {
                customBigEndian = (customBigEndian === false ? customBigEndian : bigEndian);
                var r = BitUtil.getShort(getter, position, customBigEndian);
                position += 2;
                return r;
            },

            readInt: function(customBigEndian) {
                customBigEndian = (customBigEndian === false ? customBigEndian : bigEndian);
                var r = BitUtil.getInt(getter, position, customBigEndian);
                position += 4;
                return r;
            },
            readFloat: function(customBigEndian) {
                customBigEndian = (customBigEndian === false ? customBigEndian : bigEndian);
                var r = BitUtil.getFloat(getter, position, customBigEndian);
                position += 4;
                return r;
            },
            readDouble: function(customBigEndian) {
                customBigEndian = (customBigEndian === false ? customBigEndian : bigEndian);
                var r = BitUtil.getDouble(getter, position, customBigEndian);
                position += 8;
                return r;
            },
            // js不支持64位的long, Number安全整数为53位，64位long会出现丢失
            /*readLong: function() {

            }*/
            position: function() {
                return position;
            },

            skip: function(skip) {
                position += skip;
            }
        }
    }
});


;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.tools = factory();
    }
})($videojsTools, function() {
    function equals(template, bytes, offset) {
        if (offset === undefined || offset === null) {
            offset == 0;
        }
        if (offset < 0) {
            offset = bytes.length + offset;
        }

        for(var i = offset; i < template.length; i++) {
            if (template[i] != bytes[i]) {
                return false;
            }
        }
        return true;
    }

    function subASKII(bytes, start, len) {
        var str = "";
        for (var i = start, l = Math.min(bytes.length, start + len); i < l; i++) {
            str += String.fromCharCode(bytes[i]);
        }
        return str;
    }
    return {
        equals: equals,
        subASKII: subASKII,
    };
})





;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.gif = factory();
    }
})(videojs.wrapperFactory, function() {
    function isGifTag(bytes) {
        return $videojsTools.tools.equals([0X47, 0X49, 0X46], bytes, 0);
    }

    function gifVersion(bytes) {
        return $videojsTools.tools.subASKII(bytes, 3, 3);
    }
    // Logical Screen Descriptor
    function LSD(reader) {

        var size = {
            LS_Width: reader.readShort(),
            LS_Height: reader.readShort()
        }
        var flag = reader.read();
        return {
            ...size,
            bgColorIndex: reader.read(),
            pixel: reader.read(),
            GCT_Flag: 0 != (flag & 0x80),
            CR: (flag & 0x70) >> 4,
            S: 0 != flag & 0x08,
            GCT_Size: flag & 0x07,
        }
    }

    // Image Descriptor
    function ImageDescriptor(reader, introducer) {
        if (introducer !== 0x2c) {
            return;
        }
        var rst = {
            offsetX: reader.readShort(),
            offsetY: reader.readShort(),
            imageWidth: reader.readShort(),
            imageHeight: reader.readShort()
        }
        var flag = reader.read();
        return {
            ...rst,
            // Local Color Table Flag
            LCT_Flag: 0 != (flag & 0x80),
            // Interlace Flag
            I_Flag: 0 != (flag & 0x40),
            // Sort Flag
            S_Flag: 0 != (flag & 0x20),
            pixel: flag & 0x07
        }
    }
    function length(reader, version) {
        reader.skip(6);
        var lsd = LSD(reader);
        if (lsd.GCT_Flag) {
            reader.skip((2 << lsd.GCT_Size) *3);
        }
        while(true) {
            var introducer = reader.read();
            // Image Descriptor
            if (introducer == 0x2c) {
                skipImageDescriptorAndImageData(reader, introducer);
                continue;
            }
            if (introducer == 0x3B) {
                break;
            }
            if(version == "89a") {
                if (introducer == 0x21) {
                    var lable = reader.read();
                    var blockSize = reader.read();
                    reader.skip(blockSize);
                    readSubBlocks(reader);
                    continue;
                }
            }
            throw "unsupported introducer for " + introducer;
        }
        return reader.position();
    }
    function readSubBlocks(reader) {
        while(true) {
            var blockSize = reader.read();
            reader.skip(blockSize);
            if (blockSize <= 0) {
                break;
            }
        }
    }
    function skipImageDescriptorAndImageData(reader, introducer) {
        var imageDescriptor = ImageDescriptor(reader, introducer);
        if (imageDescriptor.LCT_Flag) {
            reader.skip(2 << imageDescriptor.pixel);
        }
        // lzwMinimumCodeSize
        reader.read();
        readSubBlocks(reader);
    };

    return {
        isSupport: function(bytes) {
            return isGifTag(bytes);
        },
        warpperLength: function(bytes) {
            if (!isGifTag(bytes)) {
                throw "unsupported tag";
            }
            var DataReader = $videojsTools.DataReader;
            return length(new DataReader(bytes), gifVersion(bytes));
        }
    }
});




;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.png = factory();
    }
})(videojs.wrapperFactory , function() {
    var crc32_table =
        [
            0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
            0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
            0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
            0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
            0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
            0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
            0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
            0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
            0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
            0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
            0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
            0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
            0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
            0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
            0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
            0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
            0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
            0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
            0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
            0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
            0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
            0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
            0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
            0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
            0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
            0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
            0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
            0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
            0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
            0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
            0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
            0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
            0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
            0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
            0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
            0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
            0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
            0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
            0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
            0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
            0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
            0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
            0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
            0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
            0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
            0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
            0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
            0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
            0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
            0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
            0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
            0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
            0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
            0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
            0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
            0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
            0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
            0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
            0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
            0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
            0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
            0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
            0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
            0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
        ];
    function crc32 (reader, len){
        var crc = 0xffffffff;
        while (len-- > 0) {
            crc = (crc << 8) ^ crc32_table[((crc >>> 24) ^ reverseBit(reader.read())) & 255];
        }
        return ~reverseIntBit(crc);
    }
    function reverseBit(num) {
        num = (((num & 0xaa) >>> 1) | ((num & 0x55) << 1));
        num = (((num & 0xcc) >>> 2) | ((num & 0x33) << 2));
        return ((num >>> 4) | (num << 4));
    }
    function reverseIntBit(num) {
        num = (((num & 0xaaaaaaaa) >>> 1) | ((num & 0x55555555) << 1));
        num = (((num & 0xcccccccc) >>> 2) | ((num & 0x33333333) << 2));
        num = (((num & 0xf0f0f0f0) >>> 4) | ((num & 0x0f0f0f0f) << 4));
        num = (((num & 0xff00ff00) >>> 8) | ((num & 0x00ff00ff) << 8));
        return((num >>> 16) | (num << 16));
    }

    function isPngTag(bytes) {
        return $videojsTools.tools.equals([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A], bytes, 0);
    }
    function length(reader) {
        reader.skip(8);
        var len = 0;
        var tag = 0;
        while( true ) {
            len = reader.readInt();
            tag = reader.readInt();
            reader.skip(-4);
            var chk = crc32(reader, len+4, 0x0);
            var c = reader.readInt();
            // iend 结束数据块, 或校验失败
            if (tag == 1229278788) {
                break;
            }
            if (chk !== c) {
                console.warn("crc not match, position=" + reader.position());
                break;
            }
        }
        return reader.position();
    }
    return {
        isSupport: function(bytes) {
            return isPngTag(bytes);
        },
        warpperLength: function(bytes) {
            if (!isPngTag(bytes)) {
                throw "unsupported tag";
            }
            var DataReader = $videojsTools.DataReader;
            return length(new DataReader(bytes));
        }
    }
});



;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.jpg = factory();
    }
})(videojs.wrapperFactory , function() {
    function isJpgTag(bytes) {
        return $videojsTools.tools.equals([0xFF, 0xD8], bytes, 0);
    }
    function readTag(reader) {
        while(true) {
            var tag = reader.read();
            if (tag !== 0xff) {
                continue;
            }
            var tag2 = reader.read();
            if (tag2 === 0xff) {
                reader.skip(-1);
                continue;
            }
            if (tag2 == 0xD8 || tag2 == 0xD9 || tag2 == 0xDA || tag2 == 0xDB ||
                tag2 == 0xC4 || tag2 == 0xC0 ||
                (tag2 <= 0xEF && tag2 >= 0xE0)) {
                return tag2;
            }
        }
        return -1;
    }

    function length(reader) {
        while( true ) {
            var tag = reader.read();
            if (tag !== 0xff) {
                throw "unsupported tag for " + tag;
            }
            var tag2 = reader.read();
            // 开始标记
            if (tag2 === 0xD8) {
                continue;
            }
            if (tag2 === 0xD9) {
                break;
            }
            if (tag2 === 0xff) {
                reader.skip(-1);
                continue;
            }
            var size = reader.readShort();
            reader.skip(size-2);
            if (tag2 === 0xDA) {
                // 读数据块直到遇见下一个标记
                readTag(reader);
                reader.skip(-2);
                continue;
            }
        }
        // 442822
        return reader.position();
    }
    return {
        isSupport: function(bytes) {
            return isJpgTag(bytes);
        },

        warpperLength: function(bytes) {
            // 初步判断是否为jpg格式
            if (!isJpgTag(bytes)) {
                throw "unsupported tag";
            }
            var DataReader = $videojsTools.DataReader;
            var len = 0;
            // 不符jpg格式
            try{
                len = length(new DataReader(bytes));
            }
            catch(e){
                throw e;
            }
            return len;
        }
    }
});



;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.bmp = factory();
    }
})(videojs.wrapperFactory , function() {
    function isBmpTag(bytes) {
        var equals = $videojsTools.tools.equals;
        return equals([0x42, 0x4D], bytes, 0) && equals([0x00, 0x00, 0x00, 0x00], bytes, 6);
    }
    return {
        isSupport: function(bytes) {
            return isBmpTag(bytes);
        },

        warpperLength: function(bytes) {

            if (!isBmpTag(bytes)) {
                throw "unsupported tag";
            }
            var reader = new $videojsTools.DataReader(bytes);
            reader.skip(2);
            return reader.readInt(false);
        }
    }
});




;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.ico = factory();
    }
})(videojs.wrapperFactory , function() {
    function isIcoTag(bytes) {
        var equals = $videojsTools.tools.equals;
        return equals([0x00, 0x00], bytes, 0) && (bytes[2] == 1 || bytes[2] == 2) && bytes[3] == 0;
    }

    function length(reader) {
        reader.skip(4);
        var len = reader.readShort(false);
        var end = -1;
        while(len-- > 0) {
            reader.skip(8);
            var size = reader.readInt(false);
            var offset = reader.readInt(false);
            if (size + offset > end) {
                end = size + offset;
            }
        }
        return end;
    }
    return {
        isSupport: function(bytes) {
            return isIcoTag(bytes);
        },

        warpperLength: function(bytes) {
            if (!isIcoTag(bytes)) {
                throw "unsupported tag";
            }
            return length(new $videojsTools.DataReader(bytes));
        }
    }
});



;(function(root, factory){
    if (typeof exports === "object") {
        // CommonJS
        module.exports = exports = factory();
    }
    else if (typeof define === "function" && define.amd) {
        // AMD
        define([], factory);
    }
    else {
        // Global (browser)
        root.webp = factory();
    }
})(videojs.wrapperFactory , function() {
    function isWebpTag(bytes) {
        var equals = $videojsTools.tools.equals;
        return equals([0x52, 0x49, 0x46, 0x46], bytes, 0) && equals([0x57, 0x45, 0x42, 0x50], bytes, 8);
    }
    return {
        isSupport: function(bytes) {
            return isWebpTag(bytes);
        },

        warpperLength: function(bytes) {
            if (!isWebpTag(bytes)) {
                throw "unsupported tag";
            }
            var reader = new $videojsTools.DataReader(bytes);
            reader.skip(4);
            var size = reader.readInt(false);
            if (size % 2 == 1) {
                size += 1;
            }
            return  size + 8;
        }
    }
});